home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 April: Mac OS SDK / Dev.CD Apr 96 SDK / Dev.CD Apr 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc Development Framework / ODFDev / ODF / OS / FWODUtil / Sources / FWFxMath.cpp < prev    next >
Encoding:
Text File  |  1995-11-08  |  8.1 KB  |  321 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                FWFxMath.cpp
  4. //    Release Version:    $ 1.0d11 $
  5. //
  6. //    Copyright:    © 1993, 1995 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWOS.hpp"
  11.  
  12. #ifndef FWFXMATH_H
  13. #include "FWFxMath.h"
  14. #endif
  15.  
  16. #ifndef FWSTREAM_H
  17. #include "FWStream.h"
  18. #endif
  19.  
  20. #ifdef FW_DEBUG
  21. #include <stdio.h>
  22. #endif
  23.  
  24. //========================================================================================
  25. //    RunTime Info
  26. //========================================================================================
  27.  
  28. #if FW_LIB_EXPORT_PRAGMAS
  29. #pragma lib_export on
  30. #endif
  31.  
  32. #ifdef FW_BUILD_MAC
  33. #pragma segment FWODUtil_FixedMath
  34. #endif
  35.  
  36. //========================================================================================
  37. // CLASS FW_CFixed
  38. //========================================================================================
  39.  
  40. //----------------------------------------------------------------------------------------
  41. //    FW_CFixed::Sin
  42. //----------------------------------------------------------------------------------------
  43.  
  44. FW_CFixed FW_CFixed::Sin() const
  45. {
  46.     ODFract fract = ODFractSinCos(fRep, NULL);
  47.     return FW_CFixed(fract >> 14);
  48. }
  49.  
  50. //----------------------------------------------------------------------------------------
  51. //    FW_CFixed::Cos
  52. //----------------------------------------------------------------------------------------
  53.  
  54. FW_CFixed FW_CFixed::Cos() const
  55. {
  56.     ODFract frac;
  57.     ODFractSinCos(fRep, &frac);
  58.     return FW_CFixed(frac >> 14);
  59. }
  60.  
  61. //----------------------------------------------------------------------------------------
  62. //    FW_CFixed::Sqrt
  63. //----------------------------------------------------------------------------------------
  64.  
  65. FW_CFixed FW_CFixed::Sqrt() const
  66. {
  67.     ODWide wide;
  68.     wide.hi = 0;
  69.     wide.lo = fRep;
  70.     ODWideShift(&wide, -16);
  71.     
  72.     ODFixed fixed = ODWideSquareRoot(&wide);
  73.     return FW_CFixed(fixed);
  74. }
  75.  
  76. //========================================================================================
  77. // CLASS FW_CWide
  78. //========================================================================================
  79.  
  80. //----------------------------------------------------------------------------------------
  81. //    FW_IntToWide
  82. //----------------------------------------------------------------------------------------
  83.  
  84. FW_CWide FW_FUNC_ATTR FW_IntToWide(int i)
  85. {
  86.     return FW_CWide(i, 0);
  87. }
  88.  
  89. //----------------------------------------------------------------------------------------
  90. //    FW_ODFixedToWide
  91. //----------------------------------------------------------------------------------------
  92.  
  93. FW_CWide FW_FUNC_ATTR FW_ODFixedToWide(ODFixed f)
  94. {
  95.     ODWide wide;
  96.     wide.hi = 0;
  97.     wide.lo = f;
  98.     ODWideShift(&wide, -16);
  99.     return FW_CWide(wide);
  100. }
  101.  
  102. //----------------------------------------------------------------------------------------
  103. //    FW_CWide::FW_CWide
  104. //----------------------------------------------------------------------------------------
  105.  
  106. FW_CWide::FW_CWide(FW_CFixed f)
  107. {
  108.     fRep.hi = 0;
  109.     fRep.lo = f.AsODFixed();
  110.     ODWideShift(&fRep, -16);
  111. }
  112.  
  113. //----------------------------------------------------------------------------------------
  114. //    FW_CWide::AsInt
  115. //----------------------------------------------------------------------------------------
  116.  
  117. int FW_CWide::AsInt() const
  118. {
  119.     // Rounding
  120.     ODWide wide = fRep;
  121.     ODWide half;
  122.     half.hi = 0;
  123.     half.lo = 0x80000000l;
  124.     ODWideAdd(&wide, &half);
  125.     
  126.     return wide.hi;
  127. }
  128.  
  129. //----------------------------------------------------------------------------------------
  130. //    FW_CWide::AsODFixed
  131. //----------------------------------------------------------------------------------------
  132.  
  133. ODFixed FW_CWide::AsODFixed() const
  134. {
  135.     ODWide wide = fRep;
  136.  
  137.     // Rounding
  138.     ODWide half;
  139.     half.hi = 0;
  140.     half.lo = 0x00008000l;
  141.     ODWideAdd(&wide, &half);
  142.  
  143.     if(wide.hi > 0x7FFF)
  144.         return 0x7FFFFFFFl;
  145.         
  146.     if(wide.lo < 0x8000)
  147.         return 0x80000000l;
  148.         
  149.     return (wide.hi << 16) | (wide.lo >> 16);
  150. }
  151.  
  152. //----------------------------------------------------------------------------------------
  153. //    FW_CWide::operator FW_CFixed
  154. //----------------------------------------------------------------------------------------
  155.  
  156. FW_CWide::operator FW_CFixed() const
  157. {
  158.     return FW_ODFixedToFixed(AsODFixed());
  159. }
  160.  
  161. //----------------------------------------------------------------------------------------
  162. //    FW_CWide::operator +
  163. //----------------------------------------------------------------------------------------
  164.  
  165. FW_CWide FW_FUNC_ATTR operator +    (const FW_CWide& w1, const FW_CWide& w2)
  166. {
  167.     ODWide w = w1.fRep;
  168.     ODWideAdd(&w, &w2.fRep);
  169.     return FW_CWide(w);
  170. }
  171.  
  172. //----------------------------------------------------------------------------------------
  173. //    FW_CWide::operator -
  174. //----------------------------------------------------------------------------------------
  175.  
  176. FW_CWide FW_FUNC_ATTR operator -    (const FW_CWide& w1, const FW_CWide& w2)
  177. {
  178.     ODWide w = w1.fRep;
  179.     ODWideSubtract(&w, &w2.fRep);
  180.     return FW_CWide(w);
  181. }
  182.  
  183. //----------------------------------------------------------------------------------------
  184. //    FW_WideMultiply
  185. //----------------------------------------------------------------------------------------
  186.  
  187. FW_CWide FW_FUNC_ATTR FW_WideMultiply    (FW_CFixed f1, FW_CFixed f2)
  188. {
  189.     ODWide w;
  190.     ODWideMultiply(f1.fRep, f2.fRep, &w);
  191.     return FW_CWide(w);
  192. }
  193.  
  194. //----------------------------------------------------------------------------------------
  195. //    operator /
  196. //----------------------------------------------------------------------------------------
  197.  
  198. FW_CFixed FW_FUNC_ATTR operator /    (const FW_CWide& w1, FW_CFixed f2)
  199. {
  200.     return FW_CFixed(ODWideDivide(&w1.fRep, f2.fRep, NULL));
  201. }
  202.  
  203. //========================================================================================
  204. //    Global operators << and >>
  205. //========================================================================================
  206.  
  207. FW_FUNC_ATTR const FW_CWritableStream& operator<<(const FW_CWritableStream& stream, const FW_CFixed& fx)
  208. {
  209.     return stream << fx.fRep;
  210. }
  211.  
  212. FW_FUNC_ATTR const FW_CReadableStream& operator>>(const FW_CReadableStream& stream, FW_CFixed& fx)
  213. {
  214.     return stream >> fx.fRep;
  215. }
  216.  
  217. #ifdef FW_DEBUG
  218.  
  219. //========================================================================================
  220. //    Debug versions of math operators
  221. //========================================================================================
  222.  
  223. static void FixedError(FW_CFixed f1, FW_CFixed f2, const char* lpsz)
  224. {
  225.     char buf[250];
  226.     sprintf(buf, "Fixed error: %s, %.2f, %.2f", lpsz, f1.AsDouble(), f2.AsDouble());
  227.     FW_DEBUG_MESSAGE(buf);
  228. }
  229.  
  230. FW_FUNC_ATTR
  231. FW_CFixed operator+(FW_CFixed f1, FW_CFixed f2)
  232. {
  233.     long rep1 = f1.fRep;
  234.     long rep2 = f2.fRep;
  235.  
  236.     long repr  = (rep1 >> 16) + (rep2 >> 16);
  237.  
  238.     if (repr < -32768 || repr > 32767)
  239.         FixedError(f1, f2, "Add oflw");
  240.  
  241.     return FW_CFixed(f1.fRep + f2.fRep);
  242. }
  243.  
  244. FW_FUNC_ATTR
  245. FW_CFixed operator-(FW_CFixed f1, FW_CFixed f2)
  246. {
  247.     long rep1 = f1.fRep;
  248.     long rep2 = f2.fRep;
  249.  
  250.     long repr  = (rep1 >> 16) - (rep2 >> 16);
  251.  
  252.     if (repr < -32768 || repr > 32767)
  253.         FixedError(f1, f2, "Sub oflw");
  254.  
  255.     return FW_CFixed(f1.fRep - f2.fRep);
  256. }
  257.  
  258. FW_FUNC_ATTR
  259. FW_CFixed operator*(FW_CFixed f1, FW_CFixed f2)
  260. {
  261.     long rep1 = f1.fRep;
  262.     long rep2 = f2.fRep;
  263.  
  264.     long repr  = (rep1 >> 16) * (rep2 >> 16);
  265.     
  266.     if (repr < -32768 || repr > 32767)
  267.         FixedError(f1, f2, "Mul oflw");
  268.  
  269.     return FW_CFixed(ODFixedMultiply(f1.fRep, f2.fRep));
  270. }
  271.  
  272. FW_FUNC_ATTR
  273. FW_CFixed operator/(FW_CFixed f1, FW_CFixed f2)
  274. {
  275.     if (f2.fRep == 0)
  276.         FixedError(f1, f2, "Div by 0");
  277.  
  278.     return FW_CFixed(ODFixedDivide(f1.fRep, f2.fRep));
  279. }
  280.  
  281. #endif
  282.  
  283. #ifdef FW_BUILD_WIN
  284. // [KVV] OpenDoc DR2 for Windows is missing the following routines
  285.  
  286. #include <math.h>
  287.  
  288. FW_FUNC_ATTR
  289. ODFract    ODFractSinCos(ODFixed angle, ODFract *cosResult)
  290. {
  291.     double flAngle    = ODFixedToFloat(angle);
  292.  
  293.     double flSin    = sin(flAngle);
  294.     double flCos    = cos(flAngle);
  295.     
  296.     ODFixed fxSin    = ODFloatToFixed(flSin);
  297.     ODFixed fxCos    = ODFloatToFixed(flCos);
  298.     
  299.     if(cosResult != NULL)
  300.         *cosResult = ODFixedToFract(fxCos);
  301.         
  302.     return ODFixedToFract(fxSin);
  303. }
  304.  
  305. FW_FUNC_ATTR
  306. ODULong ODWideSquareRoot(const ODWide *src)
  307. {
  308.     if(src->hi == 0 && src->lo == 0)
  309.         return 0;
  310.  
  311.     if(src->hi < 0)
  312.         return 0x7FFFFFFFl;
  313.         
  314.     double d = src->hi + src->lo / 4294967296.0;
  315.     double s = sqrt(d);
  316.     
  317.     return ODFloatToFixed(s);
  318. }
  319.  
  320. #endif
  321.